﻿using System;
using System.Collections.Generic;
using System.Linq;
using Identity;
using Microsoft.AspNetCore.Identity;
using Ornament.ImportHelper;

namespace Fee.IO.Importers
{
    public class UserImport<T> : BaseImporter<T> where T : FeeDbContext
    {
        private readonly UserManager<User> _manager;

        public UserImport(T context, UserManager<User> manager) : base(context, true)
        {
            _manager = manager;
        }

        public override void SaveToDb(IList<ImportResultItem> importResult, T t)
        {
            foreach (var item in importResult)
                foreach (RoleUser userData in item.Data)
                {
                    var error = userData.User.SecurityStamp != null
                        ? _manager.UpdateAsync(userData.User).Result
                        : _manager.CreateAsync(userData.User, userData.Password).Result;

                    if (!error.Succeeded)
                    {
                        var ary = error.Errors.Select(f => f.Description);
                        var desc = string.Join(",", ary);
                        item.AddError(0, desc);
                    }
                    else
                    {
                        foreach (var role in userData.Roles)
                        {
                            var id = _manager.AddToRoleAsync(userData.User, role.Name).Result;
                            var ary = id.Errors.Select(f => f.Description);
                            var desc = string.Join(",", ary);
                            item.AddError(0, desc);
                        }
                    }
                }
        }

        protected override bool ConverTo(IList<string> rowStringInfo, out ImportResultItem item)
        {
            item = new ImportResultItem();
            var userName = rowStringInfo.ImportString(0, "登录", item, true);
            var name = rowStringInfo.ImportString(1, "名字", item, false);
            if (string.IsNullOrEmpty(name)) name = userName;

            var roleExp = rowStringInfo.ImportString(2, "角色", item);
            string[] roles = null;
            if (!string.IsNullOrEmpty(roleExp))
                roles = roleExp.Split(new[] { ',', '，', ' ' }, StringSplitOptions.RemoveEmptyEntries);
            var pwd = rowStringInfo.ImportString(3, "密码", item);

            var distrcitName = rowStringInfo.ImportString(4, "分公司", item, false);
            var district = Context.Districts.FirstOrDefault(f => f.Name == distrcitName);

            var user = _manager.FindByNameAsync(userName).Result ?? new User
            {
                UserName = userName
            };
            user.Name = name;

            user.District = district;

            if (item.HasError == false && roles != null)
            {
                var roleObj = Context.Roles.Where(_ => roles.Contains(_.Name)).ToArray();
                var expect = roles.Except(roleObj.Select(role => role.Name));
                if (expect.Any())
                {
                    item.AddError(2, "找不到角色 " + string.Join(",", expect));
                }
                else
                {
                    var f = new RoleUser
                    {
                        Password = pwd,
                        User = user,
                        Roles = roleObj
                    };
                    if (!item.HasError) item.Data.Add(f);
                }
            }

            return !item.HasError;
        }

        public class RoleUser
        {
            public User User { get; set; }
            public Role[] Roles { get; set; }
            public string Password { get; set; }
        }
    }
}